
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity lab2 is
	port(   key : in std_logic_vector(3 downto 0);  -- pushbutton switches
        lcd_rw : out std_logic;
        lcd_en : out std_logic;
        lcd_rs : out std_logic;
        lcd_on : out std_logic;
        lcd_blon : out std_logic;
        lcd_data : out std_logic_vector(7 downto 0));
end lab2 ;


architecture behavioural of lab2 is
begin

        lcd_blon <= '1';
        lcd_on <= '1';
        lcd_en <= key(0);
        lcd_rw <= '0';
			
		  process (key(0),key(3))
		  -- I'm thinking of using the name for state instead of hardcoded values... We can define state names we want...
        type state_type is (ISTR1, ISTR2, ISTR3, ISTR4, ISTR5, ISTR6,CHAR1, CHAR2, CHAR3, CHAR4, CHAR5);
		  --added two variables for current and next state
		  --variable PRESENT_STATE : std_logic_vector(3 downto 0);
		  --variable NEXT_STATE : std_logic_vector(3 downto 0);
		  variable PRESENT_STATE : state_type;
		  variable NEXT_STATE : state_type;
		  begin
				--Implementing asynchronous reset
				if( key(3) = '0') then
				-- PRESENT_STATE := X"0"; -- reset brings the state machine to state 0x0
				-- lcd_data <= X"38"; --makes sure the LCD receives signal 0x38 from state 0x0-> I don't think we need this part. State 0x0 already implements this.
			      NEXT_STATE := ISTR1;
				--Implementing the state machine (please make changes and mark them down if you see that 
				-- something could be implemented better :) ) --> Now we can use the name of the states. Easier to read :)
				elsif (Key(0)'event and key(0)='1') then
					case PRESENT_STATE is -- Listing all cases for states transition
--						when X"0"=> NEXT_STATE := X"1";
--						when X"1"=> NEXT_STATE := X"2";
--						when X"2"=> NEXT_STATE := X"3";
--						when X"3"=> NEXT_STATE := X"4";
--						when X"4"=> NEXT_STATE := X"5";
--						when X"5"=> NEXT_STATE := X"6";
--						when X"6"=> NEXT_STATE := X"7";
--						when X"7"=> NEXT_STATE := X"8";
--						when X"8"=> NEXT_STATE := X"9";
--						when X"9"=> NEXT_STATE := X"A";
--						when others => NEXT_STATE := X"6"; -- Ensures going to 0x6 from state 0xA
						when ISTR1 => NEXT_STATE := ISTR2;
						when ISTR2 => NEXT_STATE := ISTR3;
						when ISTR3 => NEXT_STATE := ISTR4;
						when ISTR4 => NEXT_STATE := ISTR5;
						when ISTR5 => NEXT_STATE := ISTR6;
						when ISTR6 => NEXT_STATE := CHAR1;
						when CHAR1 => NEXT_STATE := CHAR2;
						when CHAR2 => NEXT_STATE := CHAR3;
						when CHAR3 => NEXT_STATE := CHAR4;
						when CHAR4=> NEXT_STATE := CHAR5;
						when others => NEXT_STATE := CHAR1;
					end case;
				end if;
					PRESENT_STATE := NEXT_STATE; --State transition 
					
				--	case PRESENT_STATE is --I implemented those according to the slides online.
												-- We will have to think of a way to make it more concise maybe? :)
				-- Is this a typo? ... The value should be NEXT_STATE...
				-- Also, we need to assign the lcd_rs output ( 0 for instructions, 1 for characters).I just follow the lecture slide :)
				   case NEXT_STATE is
						when ISTR1 => lcd_data <= X"38";
                               lcd_rs <= '0';
						when ISTR2 => lcd_data <= X"38";
						             lcd_rs <= '0';
						when ISTR3 => lcd_data <= X"0C";
						             lcd_rs <= '0';
						when ISTR4 => lcd_data <= X"01";
						             lcd_rs <= '0';
						when ISTR5 => lcd_data <= X"06";
						             lcd_rs <= '0';
						when ISTR6 => lcd_data <= X"80";
						             lcd_rs <= '0';
						when CHAR1 => lcd_data <= X"4B"; --K
					                lcd_rs <= '1';	
						when CHAR2 => lcd_data <= X"5A"; --R
					                lcd_rs <= '1';
						when CHAR3 => lcd_data <= X"52"; --Z
						             lcd_rs <= '1';
						when CHAR4 => lcd_data <= X"59"; --Y
						             lcd_rs <= '1';
						when others => lcd_data <= X"53"; --S
						               lcd_rs <= '1';
					end case;
			end process;
		  -- insert your state machine here.  Remember this a Moore state machine
		  -- has an asynchronous reset. You can do it with one process, although
		  -- you may choose to break it up if you want.
		  
 
end behavioural;

